package com.forum.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import org.springframework.context.annotation.Bean;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.forum.resp.ResultData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    private static final Logger logger = LoggerFactory.getLogger(WebConfig.class);

    @Value("${forum.upload.path}")
    private String uploadPath;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 添加详细日志，帮助调试
        logger.info("配置静态资源映射：/uploads/** -> {}", "file:" + uploadPath + "/");
        
        // 注册静态资源处理器 - 注意：用户服务的context-path是/user，所以路径应该匹配
        registry.addResourceHandler("/uploads/**")
                .addResourceLocations("file:" + uploadPath + "/")
                .setCachePeriod(3600) // 设置缓存时间为1小时
                .resourceChain(true); // 启用资源链优化
                
        logger.info("静态资源映射配置完成");
    }
    
    /**
     * 统一响应处理器，但排除内部接口
     */
    @Bean
    public ResponseHandlerAdvice responseHandlerAdvice() {
        return new ResponseHandlerAdvice();
    }
    
    @RestControllerAdvice
    public static class ResponseHandlerAdvice implements ResponseBodyAdvice<Object> {
        
        @Override
        public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
            // 检查是否是内部接口（排除内部接口）
            String className = returnType.getDeclaringClass().getName();
            String methodName = returnType.getMethod().getName();
            
            // 更精确地检查是否为内部接口
            // 1. 检查类名是否包含"Internal"
            boolean isInternalClass = className.contains("Internal") || 
                                     (returnType.getDeclaringClass().getPackage() != null && 
                                     returnType.getDeclaringClass().getPackage().getName().contains("internal"));
                                     
            // 2. 检查类上是否有RequestMapping("/internal")注解
            boolean hasInternalMapping = false;
            if (returnType.getDeclaringClass().isAnnotationPresent(org.springframework.web.bind.annotation.RequestMapping.class)) {
                org.springframework.web.bind.annotation.RequestMapping mapping = 
                    returnType.getDeclaringClass().getAnnotation(org.springframework.web.bind.annotation.RequestMapping.class);
                for (String path : mapping.value()) {
                    if (path.contains("internal")) {
                        hasInternalMapping = true;
                        break;
                    }
                }
            }
            
            // 如果类名包含"Internal"或有"/internal"映射，排除该接口
            boolean isInternalEndpoint = isInternalClass || hasInternalMapping;
            
            // 另外，检查返回类型是否已经是ResultData
            boolean isAlreadyResultData = ResultData.class.isAssignableFrom(returnType.getParameterType());
            
            // 记录日志，帮助调试
            System.out.println("类: " + className + ", 方法: " + methodName + 
                             ", 是否内部端点: " + isInternalEndpoint + 
                             ", 是否已经包装: " + isAlreadyResultData +
                             ", 是否应处理: " + (!isInternalEndpoint && !isAlreadyResultData));
            
            // 如果是内部端点或已包装，不处理
            return !isInternalEndpoint && !isAlreadyResultData;
        }
        
        @Override
        public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                     Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                     ServerHttpRequest request, ServerHttpResponse response) {
            // 如果是内部调用的端点，直接返回原始结果
            if (body instanceof ResultData) {
                return body;
            }
            return ResultData.success(body);
        }
    }
}
